/* 做AJAX通信 */
// const { objToParamsStr } = require("../data_utils/string_util");

/* 
requestConf请求配置模板
{
    url: "https://www.httpbin.org/post",
    method: "post",
    data: "username=admin&password=123456",
    headers: {
        "Content-Type": "application/x-www-form-urlencoded",
        Accept: "application/json"
    },
    onSuccess(result) {
        const ret = JSON.parse(result)
        console.log("ret", ret);
    },
    onErr(err) {
        console.error(err)
        document.write(err.msg)
    }
}
*/

/* 
对象转网络请求参数串(params)形式 
例如：{username:admin,password:123456} 转化为 username=admin&password=123456
*/
// console.log(objToParamsStr({ username: "admin", password: "123456" }));
function objToParamsStr(obj) {
    // {a:1,b:2} 转化为 a=1&b=2
    let params = "";
    for (let key in obj) {
        params += `${key}=${obj[key]}&`;
    }
    params = params.slice(0, -1);
    return params;
}

function ajax(requestConf) {
    // 读取requestConf
    let { url, method, data, headers, onSuccess, onErr, resType } = requestConf;
    resType = resType || "json";

    /* 如果用户连url都没配置 则抛出错误 */
    if (!url) {
        throw new Error("请务必配置url我亲爱的傻鸟");
    }

    /* 给配置以默认值 */
    // 如果没有配置请求方法 则默认使用GET
    method = method ? method : "get";
    // 如果没有配置请求数据 则默认空
    data = data ? data : null;
    // 如果没有配置成功回调 则使用默认
    onSuccess = onSuccess
        ? onSuccess
        : (result) => {
              console.log("成功", result);
          };
    // 如果没有配置失败回调 则使用默认
    onErr = onErr
        ? onErr
        : (err) => {
              console.log("失败", err);
          };

    // 如果GET请求带data
    // 将data {username:admin,password:123456} 转化为请求参数 ?username=admin&password=123456 并拼接到url后面
    if (method.toLowerCase() === "get" && data) {
        // {a:1,b:2} 转化为 a=1&b=2
        url += `?${objToParamsStr(data)}`;
    }

    /* 如果POST请求携带了数据 且数据格式为{username:"admin",password:"123456"} 
    则先转化为参数串形式 username=admin&password=123456 */
    if (method.toLowerCase() === "post" && typeof data === "object") {
        data = objToParamsStr(data);
    }

    // 创建XHR
    const xhr = new XMLHttpRequest();

    /* 设置XHR的过程回调 */
    xhr.onreadystatechange = function () {
        /* 只关注最终的结果 */
        if (xhr.readyState === 4) {
            // 要么成功
            if (xhr.status >= 200 && xhr.status < 300) {
                // 将请求到的数据【丢还用户】

                // 用户想怎么处理，你就怎么处理
                // 通过调用成功回调帮用户处理结果
                let result = xhr.responseText;
                onSuccess(resType === "json" ? JSON.parse(result) : result);
            }

            // 重定向浏览器自己会处理，无需配置

            // 要么失败
            else {
                // 用户想怎么处理失败，你就怎么处理失败
                onErr({ status: xhr.status, msg: xhr.responseText });
            }
        }
    };

    // 建立连接
    xhr.open(method, url);

    // 有请求头则一一配置请求头
    // xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
    if (headers) {
        for (let key in headers) {
            xhr.setRequestHeader(key, headers[key]);
        }
    }

    // 发送请求+数据
    xhr.send(data);
}

/* 
requestConf模板：{ url:mathUrl, data: { a: value, b: 3 } }
*/
function ajaxPromise(requestConf) {
    return new Promise((resolve, reject) => {
        ajax({
            ...requestConf,
            onSuccess(ret) {
                // 向后传递结果：reslove
                resolve(ret);
            },
            onErr(err) {
                // 向后传递错误：reject
                reject(err);
            },
        });
    });
}
